home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / ARexxTools / fpl70.lha / funclib / lib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-10  |  5.3 KB  |  214 lines

  1. /********************************************************************
  2.  *
  3.  * This is a funclib program example. It is run from the from the
  4.  * "func" program example. It is started with a simple run and
  5.  * stopped when it receives a break-signal.
  6.  *
  7.  * This program can be made pure/re-entrant.
  8.  *
  9.  */
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/dos.h>
  13. #include <proto/fpl.h>
  14. #include <libraries/fpl.h>
  15. #include <exec/execbase.h>
  16. #include <exec/ports.h>
  17.  
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include "funclib.h"
  22.  
  23. #define TEMPLATE "Version/N/A,Anchor/N/A"
  24.  
  25. #define OURTASKNAME "FPLlib"
  26. #define OTHERTASKNAME "FPLfunc"
  27.  
  28. enum {
  29.   opt_VERSION,
  30.   opt_ANCHOR,
  31.   opt_COUNT,
  32. };
  33.  
  34. struct ReportMsg {
  35. struct Message msg;
  36. int ErrorNumber;
  37. };
  38.  
  39. extern struct ExecBase *SysBase;
  40. struct Library *FPLBase=NULL;
  41.  
  42. long __asm func(register __a0 struct fplArgument *);
  43.  
  44. void CloseOurPort(struct MsgPort *port)
  45. {
  46.   if (port){
  47.     RemPort(port);
  48.     DeleteMsgPort(port);
  49.   }
  50. }
  51.  
  52. int main(int argc, char **argv)
  53. {
  54.   LONG opts[opt_COUNT];
  55.   long version;
  56.   long anchor;
  57.   char ourportname[30];
  58.   char otherportname[30];
  59.   struct RDArgs *argsptr;
  60.   struct MsgPort *port;
  61.   struct MsgPort *otherport;
  62.   struct ReportMsg *receive;
  63.   int Error=0;
  64.   if (SysBase->LibNode.lib_Version > 36) {
  65.     argsptr = ReadArgs(TEMPLATE, opts, NULL);
  66.     if (argsptr) {
  67.       version = *((LONG *)opts[opt_VERSION]);
  68.       anchor = *((LONG *)opts[opt_ANCHOR]);
  69.       FreeArgs(argsptr);
  70.     } else {
  71.       PrintFault(IoErr(), NULL);    /* prints the appropriate err message */
  72.       return FUNCLIB_PARAMETER;
  73.     }
  74.   } else {
  75.     char Nomatch=0;
  76.     if(argc<5)
  77.       return FUNCLIB_PARAMETER;
  78.     else {
  79.       if(!strcmp("version", argv[version=1]) ||
  80.          !strcmp("anchor", argv[anchor=3]))
  81.         Nomatch=TRUE;
  82.       else if(!strcmp("version", argv[version=3]) ||
  83.          !strcmp("anchor", argv[anchor=1]))
  84.         Nomatch=TRUE;
  85.       if(Nomatch)
  86.         return FUNCLIB_PARAMETER;
  87.       version=atoi(argv[version]);
  88.       anchor=atoi(argv[anchor]);
  89.     }
  90.   }
  91.  
  92.   sprintf(ourportname, "%s.%d", OURTASKNAME, anchor);
  93.   sprintf(otherportname, "%s.%d", OTHERTASKNAME, anchor);
  94.  
  95.   /* Make our port, so that our father can find us */
  96.   if (port=CreateMsgPort()){
  97.     port->mp_Node.ln_Name=ourportname;
  98.     port->mp_Node.ln_Pri=0;
  99.     AddPort(port);
  100.   } else
  101.     return FUNCLIB_INTERNAL; /* We failed... */
  102.  
  103.   /*
  104.    * Here should the funclib perform its initializations.
  105.    */
  106.  
  107.   /*
  108.    * We check that the anchor is above 400 to prevent test
  109.    * runnings to actually try to add functions to a non-existant
  110.    * anchor.
  111.    */
  112.   if(anchor > 400) {
  113.     /* open fpl.library */
  114.     FPLBase = OpenLibrary("fpl.library", 6);
  115.  
  116.     if(!FPLBase) {
  117.       CloseOurPort(port);
  118.       return FUNCLIB_RESOURCE;
  119.     } else {
  120.       fplAddFunctionTags((void *)anchor, "libTest", 1, 'S', NULL,
  121.                          FPLTAG_FUNCTION, func, FPLTAG_DONE);
  122.     }
  123.   }
  124.  
  125.   /* Tell papa we have initialized and are ready to be used! */
  126.   Forbid();
  127.   if (otherport = FindPort(otherportname)) {
  128.     struct ReportMsg Iamup;
  129.     Iamup.msg.mn_ReplyPort=port;
  130.     Iamup.ErrorNumber=Error;
  131.     PutMsg(otherport,&Iamup.msg);
  132.     Permit();
  133.     /* Check if we have had any errors */
  134.     if (!Error) {
  135.       /* Now let's wait for our reply */
  136.       WaitPort(port);
  137.       GetMsg(port);
  138.       /* Now Iamup.ErrorNumber could be read to check for information */
  139.       /* We wait here until they tell us to close down the funclib. */
  140.       WaitPort(port);
  141.       /* (No reply before we have finished things up ...) */
  142.  
  143.     } else { /* We had an error. No reply will come. Finnish up */
  144.       /* Wait for 5 seconds, so that we are sure the message has been received */
  145.       Delay(50*5);
  146.       CloseOurPort(port);
  147.       CloseLibrary(FPLBase);
  148.       /* Return to nowhere */
  149.       return FUNCLIB_INTERNAL;
  150.     }
  151.   } else { /*
  152.             * No fatherport. This error SHOULD not be able to happen !
  153.             * since our father would not have started us if it failed
  154.             * opening that port
  155.             */
  156.     Permit();
  157.     CloseOurPort(port);
  158.     CloseLibrary(FPLBase);
  159.     return FUNCLIB_INTERNAL;
  160.   }
  161.  
  162.   /* here are all the closing down functions performed. */
  163.  
  164.   /*
  165.    * We check that the anchor is above 400 to prevent test
  166.    * runnings to actually try to delete functions with a non-existant
  167.    * anchor.
  168.    */
  169.   if (anchor > 400 && otherport) {
  170.     /* remove our test function */
  171.     fplDelFunction((void *)anchor, "libTest");
  172.  
  173.     /* close library */
  174.     CloseLibrary(FPLBase);
  175.   }
  176.  
  177.   /* tell our controller that we are about to die! */
  178.   receive=(struct ReportMsg *) GetMsg(port);
  179.   /* We could use the receive.ErrorNumber field to check for special commandos */
  180.   /* We also could write the errorfield to notify our father
  181.      if we had any errors */
  182.   ReplyMsg((struct Message *) receive);
  183.  
  184.   /*
  185.    * Right after we send that reply to our controlling process, that
  186.    * process will consider us done and continue. We do our best by
  187.    * exiting silently but have no longer any speed demands...
  188.    */
  189.  
  190.   /*
  191.    * We close our port.
  192.    */
  193.   CloseOurPort(port);
  194.  
  195.   /*
  196.    * Returning to nowhere...
  197.    */
  198.   return FUNCLIB_OK;
  199. }
  200.  
  201. long __asm func(register __a0 struct fplArgument *arg)
  202. {
  203.   /*
  204.    * Here are all our functions!
  205.    */
  206.   switch(arg->ID) {
  207.   case 1:
  208.     fplSendTags(arg->key, FPLSEND_STRING, "testlibstring", FPLTAG_DONE);
  209.     break;
  210.   default:
  211.     break;
  212.   }
  213.   return FPL_OK;
  214. }